package luke.audio.metadata;




import javax.swing.*;
import java.io.File;
import java.util.*;
import java.util.concurrent.*;


/**
 * 任务调度器 - 支持插队模式的任务管理
 */
public class TaskScheduler {
    private static TaskScheduler instance;

    // 任务队列 - 按优先级排序
    private final PriorityBlockingQueue<AnalysisTask> taskQueue;

    // 当前执行的任务
    private AnalysisTask currentTask;

    // 工作线程
    private Thread workerThread;

    // 锁对象
    private final Object lock = new Object();

    // 是否正在运行
    private volatile boolean running = true;

    TaskScheduler() {
        // 优先级队列，优先级数字大的优先（数字越大优先级越高）
        taskQueue = new PriorityBlockingQueue<>(11,
                (t1, t2) -> Integer.compare(t2.priority, t1.priority));

        // 启动工作线程
        workerThread = new Thread(this::processTasks);
        workerThread.setDaemon(true);
        workerThread.start();
    }

    public static TaskScheduler getInstance() {
        if (instance == null) {
            instance = new TaskScheduler();
        }
        return instance;
    }

    /**
     * 提交分析任务
     */
    public void submitTask(List<File> files, int priority, SongMetadataExtractor.AnalysisProgressCallback callback) {
        AnalysisTask newTask = new AnalysisTask(files, priority, callback);

        synchronized (lock) {
            // 检查是否需要插队
            if (currentTask != null && newTask.priority > currentTask.priority) {
                System.out.println("高优先级任务插队，优先级: " + newTask.priority + " > " + currentTask.priority);

                // 停止当前任务
                currentTask.cancel();

                // 将当前任务重新放回队列
                if (!currentTask.isCompleted()) {
                    taskQueue.offer(currentTask);
                }

                // 立即执行新任务
                currentTask = newTask;
                executeTask(currentTask);
            } else {
                // 普通入队
                taskQueue.offer(newTask);
                System.out.println("任务入队，优先级: " + newTask.priority + "，队列大小: " + taskQueue.size());
            }
        }
    }

    /**
     * 处理任务队列
     */
    private void processTasks() {
        while (running) {
            try {
                synchronized (lock) {
                    // 如果当前没有任务，从队列中获取
                    if (currentTask == null || currentTask.isCompleted()) {
                        currentTask = taskQueue.poll(100, TimeUnit.MILLISECONDS);
                        if (currentTask != null) {
                            executeTask(currentTask);
                        }
                    }
                }

                // 短暂休眠，避免过度占用CPU
                Thread.sleep(50);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 执行任务
     */
    private void executeTask(AnalysisTask task) {
        System.out.println("开始执行任务，优先级: " + task.priority);

        // 在新线程中执行任务，避免阻塞调度器
        new Thread(() -> {
            try {
                task.execute();
            } catch (Exception e) {
                System.err.println("任务执行失败: " + e.getMessage());
                e.printStackTrace();
            } finally {
                synchronized (lock) {
                    // 标记任务完成
                    task.markCompleted();
                    currentTask = null;
                    System.out.println("任务执行完成，优先级: " + task.priority);
                }
            }
        }).start();
    }

    /**
     * 获取队列状态
     */
    public String getQueueStatus() {
        synchronized (lock) {
            StringBuilder status = new StringBuilder();
            status.append("当前任务: ").append(currentTask != null ?
                    "运行中(优先级:" + currentTask.priority + ")" : "无").append("\n");
            status.append("等待任务: ").append(taskQueue.size()).append("个\n");

            // 显示队列中的任务优先级
            if (!taskQueue.isEmpty()) {
                status.append("队列优先级: ");
                for (AnalysisTask task : taskQueue) {
                    status.append(task.priority).append(" ");
                }
            }

            return status.toString();
        }
    }

    /**
     * 停止调度器
     */
    public void shutdown() {
        running = false;
        if (workerThread != null) {
            workerThread.interrupt();
        }

        synchronized (lock) {
            if (currentTask != null) {
                currentTask.cancel();
            }
            taskQueue.clear();
        }
    }

    /**
     * 分析任务类
     */
    private static class AnalysisTask {
        private final List<File> files;
        private final int priority;
        private final SongMetadataExtractor.AnalysisProgressCallback callback;
        private volatile boolean cancelled = false;
        private volatile boolean completed = false;
        private SwingWorker<Void, File> worker;

        public AnalysisTask(List<File> files, int priority, SongMetadataExtractor.AnalysisProgressCallback callback) {
            this.files = files;
            this.priority = priority;
            this.callback = callback;
        }

        public void execute() {
            if (cancelled) {
                return;
            }

            // 使用SongMetadataExtractor执行实际的分析工作
            SongMetadataExtractor extractor = SongMetadataExtractor.getInstance();
            worker = new SwingWorker<Void, File>() {
                @Override
                protected Void doInBackground() throws Exception {
                    // 这里调用原有的批量分析方法，但使用固定优先级
                    extractor.batchExtractMetadataInternal(files, priority, callback);
                    return null;
                }
            };

            worker.execute();

            // 等待任务完成或被取消
            try {
                while (!worker.isDone() && !cancelled) {
                    Thread.sleep(100);
                }

                if (cancelled) {
                    worker.cancel(true);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                if (!worker.isDone()) {
                    worker.cancel(true);
                }
            }
        }

        public void cancel() {
            cancelled = true;
            if (worker != null && !worker.isDone()) {
                worker.cancel(true);
            }
        }

        public boolean isCompleted() {
            return completed || (worker != null && worker.isDone());
        }

        public void markCompleted() {
            completed = true;
        }
    }
}